---
title: 'Vue component'
description: 'Learn how to use the Schedule-X calendar in a Vue application'
---

import VueIcon from "../../../../components/partials/logos/vue-icon";

# <VueIcon /> Vue component

This page offers documentation for using the Schedule-X calendar in Vue. For general documentation on
configuring the calendar, refer to the rest of the documentation. If you are using
Schedule-X with Nuxt, all code examples below should work, but everything needs to be wrapped in a
`<ClientOnly>` component.

## Installing

import { Tabs } from 'nextra/components'

<Tabs items={['npm', 'pnpm', 'yarn']}>
  <Tabs.Tab>
    ```bash copy
      npm install @schedule-x/vue @schedule-x/calendar @schedule-x/theme-default temporal-polyfill
    ```
  </Tabs.Tab>

  <Tabs.Tab>
    ```bash copy
      pnpm install @schedule-x/vue @schedule-x/calendar @schedule-x/theme-default @preact/signals preact temporal-polyfill
    ```
  </Tabs.Tab>

  <Tabs.Tab>
    ```bash copy
      yarn add @schedule-x/vue @schedule-x/calendar @schedule-x/theme-default @preact/signals preact temporal-polyfill
    ```
  </Tabs.Tab>
</Tabs>

import {Callout} from "nextra/components";

<Callout type="info">
  Curious about the `temporal-polyfill` package? Read more [here](/docs/calendar/temporal).
</Callout>

If you're using a package manager that does not automatically
download peer dependencies, you will additionally need to install `@schedule-x/calendar`, `@preact/signals` and
`preact`. This is for example the case for **yarn** and **npm < v7**.

## Basic usage

### Example

```vue
<script setup>
import { ScheduleXCalendar } from '@schedule-x/vue'
import {
  createCalendar,
  createViewDay,
  createViewMonthAgenda,
  createViewMonthGrid,
  createViewWeek,
} from '@schedule-x/calendar'
import '@schedule-x/theme-default/dist/index.css'
import 'temporal-polyfill/global'

// Do not use a ref here, as the calendar instance is not reactive, and doing so might cause issues
// For updating events, use the events service plugin
const calendarApp = createCalendar({
  selectedDate: Temporal.PlainDate.from('2023-12-19'),
  views: [
    createViewDay(),
    createViewWeek(),
    createViewMonthGrid(),
    createViewMonthAgenda(),
  ],
  events: [
    {
      id: 1,
      title: 'Event 1',
      start: Temporal.PlainDate.from('2023-12-19'),
      end: Temporal.PlainDate.from('2023-12-19'),
    },
    {
      id: 2,
      title: 'Event 2',
      start: Temporal.ZonedDateTime.from('2023-12-20T12:00:00+09:00[Asia/Tokyo]'),
      end: Temporal.ZonedDateTime.from('2023-12-20T13:00:00+09:00[Asia/Tokyo]'),
    },
  ],
})
</script>

<template>
  <div>
    <ScheduleXCalendar :calendar-app="calendarApp" />
  </div>
</template>
```

### Explanation

#### The calendar instance

The `createCalendar` function takes a [configuration object](/docs/calendar/configuration) as its single argument,
and returns an instance of the calendar app. The calendar instance contains some methods that you can use to
interact with the calendar events and toggle between light and dark mode. For more on this, refer to the rest of the
calendar docs.

#### The component

The `ScheduleXCalendar` component then takes the calendar instance as a prop `calendar-app` and renders the calendar
for you. This means you should not call the `render` method of the calendar instance yourself, as shown in other
examples in the docs.

## Styles

The Schedule-X calendar is a responsive component. To achieve this,
it cannot be delivered with a fixed height or width of its own. You need to define the height and width of the
wrapping element `.sx-vue-calendar-wrapper` according to your needs. For a regular desktop application, something
like this might do the trick for you:

```css
.sx-vue-calendar-wrapper {
  width: 1200px;
  max-width: 100vw;
  height: 800px;
  max-height: 90vh;
}
```

## Slots & custom components

The Schedule-X calendar is built with customization in mind. Using Vue slots or custom components, you can take
control over the rendering in parts of the UI. Currently, these components can be customized:

| Slot / Component name       | Description                                                         | Props                           |
|-----------------------------|---------------------------------------------------------------------|---------------------------------|
| `timeGridEvent`             | The component for timed events used in the week- and day views      | `calendarEvent`                 |
| `dateGridEvent`             | The component for all-day events used in the week- and day views    | `calendarEvent`                 |
| `weekGridDate`              | Replaces the day name and date in the header of day- and week views | `date`                          |
| `weekGridHour`              | Replaces the hour in the time axis of day- and week views           | `hour`, `gridStep`              |
| `monthGridEvent`            | The component for events used in the month grid view                | `calendarEvent`, `hasStartDate` |
| `monthGridDayName`          | Replaces day names like "Mon", "Tue" in month grid                  | `day` (0-6, like in JS-dates)   |
| `monthGridDate`             | Replaces date of month in month grid                                | `date`, `jsDate`                |
| `monthAgendaEvent`          | The component for events used in the month agenda view              | `calendarEvent`                 |
| `eventModal`                | The component for the modal that opens when clicking an event       | `calendarEvent`                 |
| `headerContentLeftPrepend`  | Prepends content to the left part of the header                     | `$app`                          |
| `headerContentLeftAppend`   | Appends content to the left part of the header                      | `$app`                          |
| `headerContentRightPrepend` | Prepends content to the right part of the header                    | `$app`                          |
| `headerContentRightAppend`  | Appends content to the right part of the header                     | `$app`                          |
| `headerContent`             | Replaces the whole header content                                   | `$app`                          |
| `sidebarAddEventButton`     | "Add event" button in the sidebar plugin                            | `onClick`                       |
| `resourceEvent`             | Event element in resource scheduler                                 | `calendarEvent`, `resource`     |

[Visual overview of all components](/docs/calendar/custom-components)

### Slot example

```vue
<template>
  <ScheduleXCalendar :calendar-app="calendarApp">
    <template #timeGridEvent="{ calendarEvent }">
      <div class="event">
        {{ calendarEvent.title }}
      </div>
    </template>
  </ScheduleXCalendar>
</template>
```

### Custom component example

```vue
<script setup>
import { ScheduleXCalendar } from '@schedule-x/vue'
import { createCalendar, createViewWeek } from '@schedule-x/calendar'
import CustomTimeGridEvent from './some-path/CustomTimeGridEvent.vue'
import '@schedule-x/theme-default/dist/index.css'
import 'temporal-polyfill/global'

const viewWeek = createViewWeek()

const calendarApp = createCalendar({
  views: [viewWeek],
  defaultView: viewWeek.name,
  events: [
    {
      id: 2,
      title: 'Event 2',
      start: Temporal.ZonedDateTime.from('2023-12-20T12:00:00+09:00[Asia/Tokyo]'),
      end: Temporal.ZonedDateTime.from('2023-12-20T13:00:00+09:00[Asia/Tokyo]'),
    },
  ],
})

const customComponents = {
  timeGridEvent: CustomTimeGridEvent,
}
</script>

<template>
  <div>
    <ScheduleXCalendar
      :calendar-app="calendarApp"
      :custom-components="customComponents"
    />
  </div>
</template>
```

## Links

Vue example: https://github.com/schedule-x/vue-example

Nuxt example: https://github.com/schedule-x/nuxt-example

Custom components example: https://github.com/schedule-x/vue-example/blob/main/src/App.vue
